//
//  MZTimer.swift
//  MZTool
//
//  Created by gby on 2022/3/8.
//

import Foundation
import CoreFoundation

public class MZTimer: NSObject {
    private enum MZDISPATCH_TIMEER_TYPE {
        case infinite
        case limited
    }
    
    //记时器
    private var timer: DispatchSource?
    private var hander:((DispatchSourceTimer?, Int) -> Void)?
    private var timeinterval: Double = 1
    private var repeatcount: Int = 0
    private var count: Int = 0
    private var type: MZDISPATCH_TIMEER_TYPE = .infinite
    
    
    var isSuspend = false
    
    deinit {
        destoryTimer()
        MZ.printLog("")
    }
    
    public override init() {
        super.init()
    }
    
    public required convenience init(handler: @escaping (DispatchSourceTimer?, Int) -> Void, _ repeatCount: Int = 0, _ timeInterval: Double = 1) {
        self.init()
        self.hander = handler
        self.repeatcount = repeatCount
        self.count = repeatCount
        self.timeinterval = timeInterval
        if repeatCount > 0 {
            self.type = .limited
        }else{
            self.type = .infinite
        }
    }
    
    public func destoryTimer() {
        stop()
        if isSuspend {
            isSuspend = false
            timer?.resume()
        }
        timer?.cancel()
        timer = nil
    }
    
    public func start() {
        if timeinterval == 0 {
            return
        }
        if timer == nil {
            timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global()) as? DispatchSource
            timer?.schedule(deadline: .now(), repeating: timeinterval, leeway: .milliseconds(10))
            self.count = self.repeatcount
            timer?.setEventHandler(handler: { [weak self] in
                if self?.type == .limited {
                    self?.count -= 1
                    DispatchQueue.main.async {
                        self?.hander?(self?.timer, self?.count ?? 0)
                    }
                    if self?.count == 0 {
                        self?.timer?.cancel()
                        self?.timer = nil
                    }
                }else{
                    DispatchQueue.main.async {
                        self?.hander?(self?.timer, 0)
                    }
                }
            })
            isSuspend = false
            timer?.resume()
        }else {
            if isSuspend {
                isSuspend = false
                timer?.resume()
            }
            if self.type == .limited, self.count <= 0 {
                timer?.cancel()
                if timer != nil {
                    timer = nil
                }
                start()
                return
            }
        }
    }
    
    public func stop() {
        if !isSuspend {
            isSuspend = true
            timer?.suspend()
        }
    }
}


